home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Trading on the Edge
/
Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin
/
pc
/
mac_file
/
software
/
nn_prepr
/
finevl.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-25
|
12KB
|
363 lines
/* 17:53 23-Aug-92 (finevl.c) Evaluation Function */
#include "fin.h"
/************************************************************************
* Copyright(C) 1992 High-Tech Communications. *
* 103 Buckskin Court, Sewickley, PA 15143 *
* *
* Written by Casimir C. Klimasauskas *
* *
* All rights reserved. No part of this program may be reproduced, *
* stored in a retrieval system, or tramsmitted, in any form or by any *
* means, electronic, mechanical, photocopying, recording or otherwise *
* without the prior written permission of the copyright owner, *
* High-Tech Communications. *
* *
* These programs are supplied on an "as-is" basis with no warranties *
* of fitness or operability, either express or implied. *
* *
************************************************************************
*/
double StdDevD( vFP, nI ) /* compute variance */
float *vFP; /* vector to work on */
int nI; /* # of items in vector */
{
double SumXD; /* sum of values */
double SumXXD; /* sum of squared values */
double vD; /* work value */
float *pF; /* work pointer */
int I; /* work index */
if ( nI <= 1 ) return( 0.0 );
for( SumXD=0.0, I=nI, pF=vFP; --I >= 0; pF++ )
SumXD += (*pF);
SumXD /= nI; /* average */
for( SumXXD=0., I=nI, pF=vFP; --I >= 0; pF++ ) {
vD = *pF - SumXD;
SumXXD += vD * vD;
}
vD = sqrt( SumXXD / (nI - 1) );
return( vD );
}
NetEvalV( NSigFP, PriceFP, DateLP,
wBSSigIP, wEqFP, wPLFP,
VecI, OptsI, prtFP,
srtLD, srtHD, buyLD, buyHD, CapitalD )
float *NSigFP; /* (i) neural net signal */
float *PriceFP; /* (i) price */
long *DateLP; /* (i) date */
int *wBSSigIP; /* (w) buy-sell signal */
float *wEqFP; /* (w) equity */
float *wPLFP; /* (w) P&L */
int VecI; /* (i) # of vector items */
int OptsI; /* (i) =1, print detail; =0, summary */
FILE *prtFP; /* (i) file pointer for printer output */
double srtLD; /* (i) low limit for srt sales */
double srtHD; /* (i) high limit for srt sales */
double buyLD; /* (i) low limit for long */
double buyHD; /* (i) high limit for long */
double CapitalD; /* (i) initial capital */
{
int rI; /* row index */
int trsI; /* transformed signal */
int bsI; /* buy-sell signal index */
int positionI; /* position -1=short; 0=out; 1=long */
int CurSigI; /* current signal */
int PrvSigI; /* previous signal */
double EquityD; /* equity */
double CurPriceD; /* current price */
double PrvPriceD; /* previous price */
double vD; /* work double */
double TransSizeD = 1000.; /* transaction size */
double TransCostD = 100.; /* transaction costs */
double GainD; /* gain on a trade */
double LossD; /* loss on a trade */
double DrawDnD; /* draw down */
int TotTradesI; /* total number of trades */
int ProfTradesI; /* profitable trades */
int runsI; /* # of runs? */
int nDrawDnI; /* # of draw downs */
int MaxDrawDnI; /* max # of drawdowns */
double MaxGainD; /* maximum gain */
double MaxLossD; /* maximum loss */
double MaxDrawDnD; /* maximum draw-down */
double TotGainD; /* total gains */
double TotLossD; /* total losses */
int numberofdaysI; /* # of days in time */
int wI; /* work int */
double SDevD; /* standard deviation */
double AvgPLD; /* average P&L */
double vX, vY, vK; /* work values */
double ZScoreD; /* Z-Score */
/* --- convert an analog signal to a short(-1)-neutral(0)-long(1) signal --- */
#define SIG(v) \
(srtLD<=(v)&&(v)<=srtHD?SHORT:((buyLD<=(v)&&(v)<=buyHD)?LONG:FLAT))
#define LONG (1)
#define FLAT (0)
#define SHORT (-1)
#define BUY LONG
#define HOLD FLAT
#define SELL SHORT
#define TRADING_DAYS 250.
if ( srtLD > srtHD ) { vD = srtLD; srtLD = srtHD; srtHD = vD; }
if ( buyLD > buyHD ) { vD = buyLD; buyLD = buyHD; buyHD = vD; }
if ( srtHD > buyLD ) { vD = (srtHD+buyLD)*.5; srtHD = buyLD = vD; }
/* --- initialize accumulators --- */
TotTradesI = 0;
ProfTradesI = 0;
runsI = 0;
nDrawDnI = 0;
MaxDrawDnI = 0;
MaxGainD = 0.0;
MaxLossD = 0.0;
MaxDrawDnD = 0.0;
TotGainD = 0.0;
TotLossD = 0.0;
/* --- Figure out buy-hold-sell signals --- */
for( rI = 0; rI < VecI; rI++ ) {
/* part 2: calculate the buy/sell signal */
trsI = SIG(NSigFP[rI]); /* generate short-neutral-long */
if ( rI == 0 ) {
bsI = positionI = trsI; /* initial values */
} else {
switch( positionI ) {
case LONG: /* current position long */
switch( trsI ) {
case LONG: bsI = BUY; positionI = LONG; break;
case FLAT:
case SHORT: bsI = SELL; positionI = FLAT; break;
}
break;
case FLAT: /* current position flat */
switch( trsI ) {
case LONG: bsI = BUY; positionI = LONG; break;
case FLAT: bsI = HOLD; positionI = FLAT; break;
case SHORT: bsI = SELL; positionI = SHORT; break;
}
break;
case SHORT: /* current position short */
switch( trsI ) {
case LONG:
case FLAT: bsI = BUY; positionI = FLAT; break;
case SHORT: bsI = SELL; positionI = SHORT; break;
}
break;
}
}
wBSSigIP[rI] = bsI;
}
/* --- Compute P&L --- */
EquityD = CapitalD; /* initial capital */
PrvPriceD = 0.0; /* nothing yet */
PrvSigI = wBSSigIP[0]; /* initial signal */
for( rI = 0; rI < VecI; rI++ ) {
/* part 3: calculate the P&L and equity from each trade */
CurSigI = wBSSigIP[rI]; /* current signal */
CurPriceD = PriceFP[rI]; /* current price */
wPLFP[rI] = 0.0; /* initialize P&L */
wEqFP[rI] = EquityD; /* initialize Equity (no trade) */
if ( rI == 0 ) {
/* --- first row of data --- */
if ( CurSigI != HOLD ) {
PrvPriceD = CurPriceD;
PrvSigI = CurSigI;
}
continue;
}
/* --- subsequent rows of data --- */
if ( CurSigI == HOLD && PrvSigI == HOLD )
continue; /* no change */
if ( (CurSigI == BUY && PrvSigI == HOLD) ||
(CurSigI == SELL && PrvSigI == HOLD) ) {
PrvPriceD = CurPriceD;
PrvSigI = CurSigI;
continue; /* bought or sold from neutral */
}
if ( CurSigI == HOLD && PrvSigI != HOLD )
/* --- when just completing a trade and going FLAT --- */
continue; /* keep current position */
/* part 4: calculate GAIN & LOSSES for each trade */
/* In this section, trades are completed. */
if ( CurSigI == SELL && PrvSigI == BUY ) {
/* 1. switching from a LONG to SHORT position */
if ( CurPriceD >= PrvPriceD ) {
/* 1.0 switch resulted in a profit */
GainD = ((CurPriceD - PrvPriceD) * TransSizeD) - TransCostD;
GainTrade:
TotTradesI++;
ProfTradesI++;
runsI++;
if ( GainD > MaxGainD ) MaxGainD = GainD;
TotGainD += GainD;
EquityD += GainD;
wEqFP[rI] = EquityD;
wPLFP[rI] = GainD;
PrvSigI = 0;
DrawDnD = 0.0;
nDrawDnI = 0;
continue;
} else {
/* 1.1 switch resulted in a loss */
LossD = ((PrvPriceD - CurPriceD)*TransSizeD) - TransCostD;
LossTrade:
TotTradesI++;
runsI++;
if ( LossD > MaxLossD ) MaxLossD = LossD;
TotLossD += LossD;
EquityD -= LossD;
wEqFP[rI] = EquityD;
wPLFP[rI] = -LossD;
/* --- Calculate Draw-down & Max Draw-down --- */
DrawDnD += LossD;
nDrawDnI++;
if ( nDrawDnI > MaxDrawDnI ) MaxDrawDnI = nDrawDnI;
if ( DrawDnD > MaxDrawDnD ) MaxDrawDnD = DrawDnD;
PrvSigI = HOLD;
continue;
}
}
if ( CurSigI == BUY && PrvSigI == SELL ) {
/* 2. Switching from a SHORT to LONG trade */
if ( CurPriceD <= PrvPriceD ) {
/* 2.0 Switch resulted in a PROFIT */
GainD = ((PrvPriceD - CurPriceD) * TransSizeD)-TransCostD;
goto GainTrade;
} else {
/* 2.1 Switch resulted in a LOSS */
LossD = ((CurPriceD - PrvPriceD) * TransSizeD)-TransCostD;
goto LossTrade;
}
}
}
/* Part 5: report output results on NN Predicted Values */
numberofdaysI = (VecI * 365.) / TRADING_DAYS;
fprintf( prtFP, "%-40s %10.2f\n",
"Period (years)", numberofdaysI/365.+0.005 );
fprintf( prtFP, "%-40s %7d\n",
"Number of Trades", TotTradesI );
fprintf( prtFP, "%-40s %7d\n",
"Profitable Trades", ProfTradesI );
fprintf( prtFP, "%-40s %10.2f %%\n",
"Profitable Trades",
TotTradesI? (100.*((double)ProfTradesI)/TotTradesI):0.0 );
fprintf( prtFP, "%-40s %10.2f\n",
"Average Trades per Year",
((double)TotTradesI)/((double)numberofdaysI) * 365. );
fprintf( prtFP, "%-40s %10.2f\n",
"Average Gain per Profitable Trade",
ProfTradesI? (TotGainD/ProfTradesI):0.0 );
wI = TotTradesI - ProfTradesI;
fprintf( prtFP, "%-40s %10.2f\n",
"Average Loss per Losing Trade",
wI? (TotLossD/wI):0.0 );
AvgPLD = TotTradesI? ((TotGainD - TotLossD)/TotTradesI):0.;
fprintf( prtFP, "%-40s %10.2f\n",
"Average P&L per Trade", AvgPLD );
SDevD = StdDevD( wPLFP, VecI );
fprintf( prtFP, "%-40s %10.2f\n",
"Standard Deviation of P&L", SDevD );
fprintf( prtFP, "%-40s %10.2f\n",
"Total P&L Over the Period", TotGainD - TotLossD );
wI = TotTradesI - ProfTradesI;
fprintf( prtFP, "%-40s %10.2f\n",
"Ratio of Profitable / Losing Trades",
wI? (((double)ProfTradesI)/wI):0. );
fprintf( prtFP, "%-40s %10.2f\n",
"Net Equity at End of Period", EquityD );
fprintf( prtFP, "%-40s %10.2f\n",
"Maximum Gain per Single Trade", MaxGainD );
fprintf( prtFP, "%-40s %10.2f\n",
"Maximum Loss per Single Trade", -MaxLossD );
fprintf( prtFP, "%-40s %10.2f\n",
"Maximum Draw Down", -MaxDrawDnD );
vD = EquityD < 0.? 0.:(pow(EquityD/CapitalD, 1./numberofdaysI) - 1.);
fprintf( prtFP, "%-40s %10.2f %%\n",
"Total Rate of Return (Daily)", vD * 100. );
vD = EquityD < 0.? 0.:(pow(EquityD/CapitalD, 1./(numberofdaysI/365.)) - 1.);
fprintf( prtFP, "%-40s %10.2f %%\n",
"Total Rate of Return (Annualized)", vD * 100. );
fprintf( prtFP, "%-40s %11.3f\n",
"Sharp Ratio", SDevD? (AvgPLD/SDevD):0. );
ZScoreD = SDevD? ((AvgPLD/SDevD)*sqrt((double)TotTradesI)):0.;
fprintf( prtFP, "%-40s %11.3f\n", "Z-Score", ZScoreD );
vX = 1.0 / ((fabs(ZScoreD) * 0.2316419) + 1.0);
vY = vX * vX;
vK = ((vX * .31938153)-(vY*.356563782)+(vX*vY*1.781477937) -
(vY*vY*1.821255978) + (vY*vY*vX*1.330274429));
vD = 1. - (2. * vK * (1./sqrt(exp(ZScoreD*ZScoreD)*6.283185307)));
fprintf( prtFP, "%-40s %11.3f\n", "Confidence Limit", vD );
fprintf( prtFP, "%-40s %10.2f\n",
"Average Profit per Year",
(TotGainD - TotLossD)/(numberofdaysI/365.) );
if ( MaxDrawDnD == 0. ) vD = 0.;
else vD = ((TotGainD - TotLossD)/(numberofdaysI/365.)) / MaxDrawDnD;
fprintf( prtFP, "%-40s %10.2f\n",
"Average Profit / Max Draw Down", vD );
vD = (PriceFP[VecI-1] - PriceFP[0]) / PriceFP[0];
fprintf( prtFP, "%-40s %10.2f %%\n", "Buy & Hold", vD*100. );
if ( OptsI ) {
/* --- Print out details --- */
fprintf( prtFP,
"\n Date Price Signal B/S P&L Equity\n\n" );
for( rI = 0; rI < VecI; rI++ )
fprintf( prtFP, "%10s%10.2f%10.2f%10d%10.2f%10.2f\n",
Date2StrCP( DateLP[rI] ),
PriceFP[rI], NSigFP[rI], wBSSigIP[rI], wPLFP[rI], wEqFP[rI] );
fprintf( prtFP, "\n" );
}
fflush( prtFP );
return( 0 );
}